using System;
using System.Collections.Generic;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.ServiceObjects;

namespace OracleInternal.TTC.Accessors
{
	internal class TTCXmlTypeAccessor : TTCNamedTypeAccessor
	{
		internal TTCXmlTypeAccessor(ColumnDescribeInfo colMetaData, MarshallingEngine marshallingEngine, bool bForBind)
			: base(colMetaData, marshallingEngine, bForBind, "SYS.XMLTYPE")
		{
		}

		internal void UnpickleXmlType(OracleConnectionImpl connImpl, DataUnmarshaller dataUnmarshaller, int currentRow, int columnIndex, OraXmlTypeHeader xmlTypeHeader, out OraXmlTypeData xmlTypeData)
		{
			int length = m_totalLengthOfData[currentRow];
			xmlTypeData = null;
			try
			{
				dataUnmarshaller.StartAccumulatingColumnData(currentRow, columnIndex, m_colDataSegments);
				dataUnmarshaller.UnmarshalCLR_ScanOnly(length, ref length);
				UnpickleXmlType(connImpl, m_colDataSegments, xmlTypeHeader, out xmlTypeData);
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				m_colDataSegments.Clear();
				dataUnmarshaller.m_bAccumulateByteSegments = false;
				dataUnmarshaller.m_dataSegments = null;
			}
		}

		internal void UnpickleXmlType(OracleConnectionImpl connImpl, int currentRow, OraXmlTypeHeader xmlTypeHeader, out OraXmlTypeData xmlTypeData)
		{
			List<ArraySegment<byte>> dataSegments = m_RowDataSegments[currentRow];
			UnpickleXmlType(connImpl, dataSegments, xmlTypeHeader, out xmlTypeData);
		}

		internal void UnpickleXmlType(OracleConnectionImpl connImpl, List<ArraySegment<byte>> dataSegments, OraXmlTypeHeader xmlTypeHeader, out OraXmlTypeData xmlTypeData)
		{
			xmlTypeData = null;
			try
			{
				TTCXmlTypePickler.ReadXmlHeader(connImpl, dataSegments, xmlTypeHeader);
				if (xmlTypeHeader.m_dataLength > 0)
				{
					xmlTypeData = new OraXmlTypeData();
					UnpickleXmlData(connImpl, dataSegments, xmlTypeHeader, xmlTypeData);
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		internal void UnpickleXmlData(OracleConnectionImpl connImpl, List<ArraySegment<byte>> dataSegments, OraXmlTypeHeader xmlTypeHeader, OraXmlTypeData xmlTypeData)
		{
			if (TypeOfXmlType.Clob == xmlTypeHeader.m_typeOfXmlType)
			{
				byte[] array = new byte[xmlTypeHeader.m_dataLength];
				Accessor.CopyDataToUserBuffer(dataSegments, xmlTypeHeader.m_headerLength, array, 0, (int)xmlTypeHeader.m_dataLength);
				xmlTypeData.m_typeOfXmlData = TypeOfXmlData.Clob;
				xmlTypeData.m_xmlLobLocator = array;
				return;
			}
			if (-2147483647 == (int)xmlTypeHeader.m_typeOfXmlType)
			{
				int num = (int)xmlTypeHeader.m_dataLength - 2;
				byte[] array2 = new byte[2];
				Accessor.CopyDataToUserBuffer(dataSegments, xmlTypeHeader.m_headerLength + num, array2, 0, 2);
				xmlTypeData.m_csid = TTCXmlTypePickler.ReadShortInNativeFormat(array2);
				byte[] array3 = new byte[num];
				Accessor.CopyDataToUserBuffer(dataSegments, xmlTypeHeader.m_headerLength, array3, 0, num);
				xmlTypeData.m_typeOfXmlData = TypeOfXmlData.BlobWithText;
				xmlTypeData.m_xmlLobLocator = array3;
				return;
			}
			if (TypeOfXmlType.BlobCSX == xmlTypeHeader.m_typeOfXmlType)
			{
				byte[] array4 = new byte[xmlTypeHeader.m_dataLength];
				Accessor.CopyDataToUserBuffer(dataSegments, xmlTypeHeader.m_headerLength, array4, 0, (int)xmlTypeHeader.m_dataLength);
				xmlTypeData.m_xmlLobLocator = array4;
				xmlTypeData.m_typeOfXmlData = TypeOfXmlData.BlobCSX;
				return;
			}
			if (TypeOfXmlType.String == xmlTypeHeader.m_typeOfXmlType)
			{
				int charCount = (int)xmlTypeHeader.m_dataLength;
				char[] array5 = new char[charCount];
				m_marshallingEngine.m_dbCharSetConv.ConvertBytesToChars(dataSegments, xmlTypeHeader.m_headerLength, (int)xmlTypeHeader.m_dataLength, array5, 0, ref charCount);
				xmlTypeData.m_typeOfXmlData = TypeOfXmlData.Chars;
				Array.Resize(ref array5, charCount);
				xmlTypeData.m_xmlChars = array5;
				return;
			}
			if (TypeOfXmlType.Object == xmlTypeHeader.m_typeOfXmlType)
			{
				throw new OracleException(ResourceStringConstants.XML_NOT_SUPPORTED_IMAGE_TYPE, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.XML_NOT_SUPPORTED_IMAGE_TYPE, "Object-relational", connImpl.m_pm.m_serverVersion));
			}
			throw new OracleException(ResourceStringConstants.XML_NOT_SUPPORTED_IMAGE_TYPE, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.XML_NOT_SUPPORTED_IMAGE_TYPE, "Unknonwn", connImpl.m_pm.m_serverVersion));
		}
	}
}
